package hw03;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class RelationalSignature implements Comparable<RelationalSignature>{
	
	private String source;
	private Set<Attribute> attributes;
	private List<Number> decomposition;
	private int i;
	
	public RelationalSignature(String source, List<Number> decomposition, Set<Attribute> attributes) {
		this.i = 0;
		this.source = source;
		this.decomposition = decomposition;
		this.setAttributes(attributes);
	}
	
	public RelationalSignature(String source, Set<Attribute> attributes) {
		this.i = 0;
		this.source = source;
		this.decomposition = new LinkedList<Number>();
		this.setAttributes(attributes);
	}
	
	public RelationalSignature(String source) {
		this.i = 0;
		this.source = source;
		this.decomposition = new LinkedList<Number>();
		this.setAttributes(new TreeSet<Attribute>());
	}
	
	public Set<Attribute> getAttributes() {
		return attributes;
	}
	
	public void setAttributes(Set<Attribute> attributes) {
		for(Attribute A : attributes) {
			A.setRelation(getName());
		}
		this.attributes = attributes;
	}
	
	public List<Number> getDecomposition() {
		return decomposition;
	}
	
	public String getSource() {
		return source;
	}
	
	public RelationalSignature decompose(Set<Attribute> A) {
		i++;
		List<Number> decomp = new LinkedList<Number>(getDecomposition());
		decomp.add(i);
		return new RelationalSignature(getSource(), decomp, A);
	}
	
	public void resetDecompCount() {
		i = 0;
	}
	
	public void resetDecomp() {
		i = 0;
		decomposition = new LinkedList<Number>();
	}
	
	public String getName() {
		String name = getSource();
		for(Number decomp : getDecomposition()) {
			name += decomp;
		}
		return name;
	}
	
	@Override
	public String toString() {
		String toString = getName() + "(";
		Iterator<Attribute> attributeIter = new TreeSet<Attribute>(getAttributes()).iterator();
		while(attributeIter.hasNext()) {
			toString += attributeIter.next().getName();
			if(attributeIter.hasNext()) {
				toString += ", ";
			}
		}
		return toString + ");";
	}
	
	public static RelationalSignature parse(String statement, Schema schema) {
		try {
			String[] components = statement.split("\\(|\\)");	
			String name = components[0].trim();
			Set<Attribute> attributes = Attribute.parseSet(components[1], schema);
			return new RelationalSignature(name, attributes);
		} catch(Exception e) {}
		return null;
	}

	@Override
	public int compareTo(RelationalSignature o) {
		return toString().compareTo(o.toString());
	}
	
}
